﻿/// <summary>
/// Developer: CHOOI KAH WAI
/// Last Modified: 22/11/2009
/// </summary>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.ComponentModel;
using System.Windows.Media.Media3D;
using System.Xml.Linq;

namespace ARSS.Editor.Common
{
    /// <summary>
    /// Scene node class
    /// </summary>
    public class SceneNode : INotifyPropertyChanged
    {
        #region Variables

        /// <summary>
        /// Node name
        /// </summary>
        private string name;

        /// <summary>
        /// Node 3D model file path
        /// </summary>
        private string modelPath;

        /// <summary>
        /// Translation value
        /// </summary>
        private Vector3D translation;

        /// <summary>
        /// Children nodes
        /// </summary>
        private ArrayList children;


        #endregion

        #region Properties

        /// <summary>
        /// Node name
        /// </summary>
        public string Name
        {
            get
            {
                return this.name;
            }
            set
            {
                this.name = value;
                NotifyPropertyChanged("Name");
            }
        }

        /// <summary>
        /// Node 3D model file path
        /// </summary>
        public string ModelPath
        {
            get
            {
                return this.modelPath;
            }
            set
            {
                this.modelPath = value;
                NotifyPropertyChanged("ModelPath");
            }
        }

        /// <summary>
        /// Scene node 3D model
        /// </summary>
        public ModelVisual3D Model3D { get; set; }

        /// <summary>
        /// Children nodes
        /// </summary>
        public ArrayList Children
        {
            get
            {
                return children;
            }
            set
            {
                children = value;
                NotifyPropertyChanged("Children");
            }
        }

        /// <summary>
        /// Translation
        /// </summary>
        public Vector3D Translation { get; set; }

        /// <summary>
        /// Rotation
        /// </summary>
        public Vector3D Rotation { get; set; }


        /// <summary>
        /// Scale
        /// </summary>
        public Vector3D Scale { get; set; }

        /// <summary>
        /// Parent scene node
        /// </summary>
        public SceneNode ParentNode { get; set; }


        #endregion

        #region Functions

        /// <summary>
        /// Constructor
        /// </summary>
        public SceneNode()
        {
            Children = new ArrayList();
            Name = "";
            ModelPath = "";
        }

        /// <summary>
        /// Load Scene Node
        /// </summary>
        /// <param name="nodeElement">Scene Node data</param>
        public void LoadNode(XElement nodeElement)
        {
            Name = nodeElement.Attribute("name").Value;
            ModelPath = nodeElement.Attribute("model").Value;

            // Load transformation

            // Rotation
            Vector3D vec = new Vector3D(double.Parse(nodeElement.Element("Rotate").Attribute("x").Value),
                                double.Parse(nodeElement.Element("Rotate").Attribute("y").Value),
                                 double.Parse(nodeElement.Element("Rotate").Attribute("z").Value));
            Rotation = vec;

            // Scale
            vec = new Vector3D(double.Parse(nodeElement.Element("Scale").Attribute("x").Value),
                                double.Parse(nodeElement.Element("Scale").Attribute("y").Value),
                                 double.Parse(nodeElement.Element("Scale").Attribute("z").Value));
            Scale = vec;

            // Translation
            vec = new Vector3D(double.Parse(nodeElement.Element("Translate").Attribute("x").Value),
                                double.Parse(nodeElement.Element("Translate").Attribute("y").Value),
                                 double.Parse(nodeElement.Element("Translate").Attribute("z").Value));
            Translation = vec;

            // Load children
            XElement childrenElement = nodeElement.Element("Children");
            if (childrenElement != null)
            {
                foreach (XElement child in childrenElement.Elements())
                {
                    SceneNode childNode = new SceneNode();
                    childNode.LoadNode(child);
                    childNode.ParentNode = this;
                    Children.Add(childNode);
                }
            }
        }

        #endregion


        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }


        #endregion
    }
}
